csscomputedvalues: Get rid of animated values
authorBenjamin Otte <otte@redhat.com>
Thu, 13 Sep 2012 16:11:29 +0000 (18:11 +0200)
committerBenjamin Otte <otte@redhat.com>
Mon, 17 Sep 2012 18:39:12 +0000 (20:39 +0200)
Merge the animated values code into the computed values code. This
should get rid of various bugs related to animated->computed updating.

gtk/Makefile.am
gtk/gtkcssanimatedvalues.c [deleted file]
gtk/gtkcssanimatedvaluesprivate.h [deleted file]
gtk/gtkcsscomputedvalues.c
gtk/gtkcsscomputedvaluesprivate.h
gtk/gtkstylecontext.c

index bb619a4bd76cfdcf4c64b8bbfaa8515a7d57220f..9997ccd41a3ed951a6483a4a764c70e55012c988 100644 (file)
@@ -426,7 +426,6 @@ gtk_private_h_sources =             \
        gtkcolorscaleprivate.h  \
        gtkcolorchooserprivate.h        \
        gtkcontainerprivate.h   \
-       gtkcssanimatedvaluesprivate.h   \
        gtkcssanimationprivate.h        \
        gtkcssarrayvalueprivate.h       \
        gtkcssbgsizevalueprivate.h      \
@@ -648,7 +647,6 @@ gtk_base_c_sources =                \
        gtkcombobox.c           \
        gtkcomboboxtext.c       \
        gtkcontainer.c          \
-       gtkcssanimatedvalues.c  \
        gtkcssanimation.c       \
        gtkcssarrayvalue.c      \
        gtkcssbgsizevalue.c     \
diff --git a/gtk/gtkcssanimatedvalues.c b/gtk/gtkcssanimatedvalues.c
deleted file mode 100644 (file)
index c7f9d0e..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright © 2012 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Benjamin Otte <otte@gnome.org>
- */
-
-#include "config.h"
-
-#include "gtkcssanimatedvaluesprivate.h"
-
-#include "gtkcssanimationprivate.h"
-#include "gtkcssarrayvalueprivate.h"
-#include "gtkcssenumvalueprivate.h"
-#include "gtkcssnumbervalueprivate.h"
-#include "gtkcssshorthandpropertyprivate.h"
-#include "gtkcssstringvalueprivate.h"
-#include "gtkcssstylepropertyprivate.h"
-#include "gtkcsstransitionprivate.h"
-#include "gtkstyleanimationprivate.h"
-#include "gtkstylepropertiesprivate.h"
-#include "gtkstylepropertyprivate.h"
-#include "gtkstyleproviderprivate.h"
-
-G_DEFINE_TYPE (GtkCssAnimatedValues, _gtk_css_animated_values, GTK_TYPE_CSS_COMPUTED_VALUES)
-
-static void
-gtk_css_animated_values_dispose (GObject *object)
-{
-  GtkCssAnimatedValues *values = GTK_CSS_ANIMATED_VALUES (object);
-
-  g_slist_free_full (values->animations, g_object_unref);
-  values->animations = NULL;
-
-  G_OBJECT_CLASS (_gtk_css_animated_values_parent_class)->dispose (object);
-}
-
-static void
-_gtk_css_animated_values_class_init (GtkCssAnimatedValuesClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->dispose = gtk_css_animated_values_dispose;
-}
-
-static void
-_gtk_css_animated_values_init (GtkCssAnimatedValues *animated_values)
-{
-}
-
-/* TRANSITIONS */
-
-typedef struct _TransitionInfo TransitionInfo;
-struct _TransitionInfo {
-  guint index;                  /* index into value arrays */
-  gboolean pending;             /* TRUE if we still need to handle it */
-};
-
-static void
-transition_info_add (TransitionInfo    infos[GTK_CSS_PROPERTY_N_PROPERTIES],
-                     GtkStyleProperty *property,
-                     guint             index)
-{
-  if (property == NULL)
-    {
-      guint i;
-
-      for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
-        {
-          GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i);
-
-          transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
-        }
-    }
-  else if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
-    {
-      GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
-      guint i;
-
-      for (i = 0; i < _gtk_css_shorthand_property_get_n_subproperties (shorthand); i++)
-        {
-          GtkCssStyleProperty *prop = _gtk_css_shorthand_property_get_subproperty (shorthand, i);
-
-          transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
-        }
-    }
-  else if (GTK_IS_CSS_STYLE_PROPERTY (property))
-    {
-      guint id;
-      
-      if (!_gtk_css_style_property_is_animated (GTK_CSS_STYLE_PROPERTY (property)))
-        return;
-
-      id = _gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (property));
-      g_assert (id < GTK_CSS_PROPERTY_N_PROPERTIES);
-      infos[id].index = index;
-      infos[id].pending = TRUE;
-    }
-  else
-    {
-      g_assert_not_reached ();
-    }
-}
-
-static void
-transition_infos_set (TransitionInfo  infos[GTK_CSS_PROPERTY_N_PROPERTIES],
-                      GtkCssValue    *transitions)
-{
-  guint i;
-
-  for (i = 0; i < _gtk_css_array_value_get_n_values (transitions); i++)
-    {
-      GtkStyleProperty *property;
-      GtkCssValue *prop_value;
-
-      prop_value = _gtk_css_array_value_get_nth (transitions, i);
-      if (g_ascii_strcasecmp (_gtk_css_ident_value_get (prop_value), "all") == 0)
-        property = NULL;
-      else
-        {
-          property = _gtk_style_property_lookup (_gtk_css_ident_value_get (prop_value));
-          if (property == NULL)
-            continue;
-        }
-      
-      transition_info_add (infos, property, i);
-    }
-}
-
-static GtkStyleAnimation *
-gtk_css_animated_values_find_transition (GtkCssAnimatedValues *values,
-                                         guint                 property_id)
-{
-  GSList *list;
-
-  for (list = values->animations; list; list = list->next)
-    {
-      if (!GTK_IS_CSS_TRANSITION (list->data))
-        continue;
-
-      if (_gtk_css_transition_get_property (list->data) == property_id)
-        return list->data;
-    }
-
-  return NULL;
-}
-
-static void
-gtk_css_animated_values_start_transitions (GtkCssAnimatedValues *values,
-                                           gint64                timestamp,
-                                           GtkCssComputedValues *source)
-{
-  TransitionInfo transitions[GTK_CSS_PROPERTY_N_PROPERTIES] = { { 0, } };
-  GtkCssComputedValues *computed;
-  GtkCssValue *durations, *delays, *timing_functions;
-  guint i;
-
-  computed = GTK_CSS_COMPUTED_VALUES (values);
-
-  transition_infos_set (transitions, _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_TRANSITION_PROPERTY));
-
-  durations = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_TRANSITION_DURATION);
-  delays = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_TRANSITION_DELAY);
-  timing_functions = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION);
-
-  for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
-    {
-      GtkStyleAnimation *animation;
-      GtkCssValue *start, *end;
-      double duration, delay;
-
-      if (!transitions[i].pending)
-        continue;
-
-      duration = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, transitions[i].index), 100);
-      delay = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, transitions[i].index), 100);
-      if (duration + delay == 0.0)
-        continue;
-
-      start = _gtk_css_computed_values_get_intrinsic_value (source, i);
-      end = _gtk_css_computed_values_get_intrinsic_value (computed, i);
-      if (_gtk_css_value_equal (start, end))
-        {
-          if (GTK_IS_CSS_ANIMATED_VALUES (source))
-            {
-              animation = gtk_css_animated_values_find_transition (GTK_CSS_ANIMATED_VALUES (source), i);
-              if (animation)
-                values->animations = g_slist_prepend (values->animations, g_object_ref (animation));
-            }
-        }
-      else
-        {
-          animation = _gtk_css_transition_new (i,
-                                               start,
-                                               end,
-                                               _gtk_css_array_value_get_nth (timing_functions, i),
-                                               timestamp + delay * G_USEC_PER_SEC,
-                                               timestamp + (delay + duration) * G_USEC_PER_SEC);
-          values->animations = g_slist_prepend (values->animations, animation);
-        }
-    }
-}
-
-static GtkStyleAnimation *
-gtk_css_animated_values_find_animation (GtkCssAnimatedValues *values,
-                                        const char           *name)
-{
-  GSList *list;
-
-  for (list = values->animations; list; list = list->next)
-    {
-      if (!GTK_IS_CSS_ANIMATION (list->data))
-        continue;
-
-      if (g_str_equal (_gtk_css_animation_get_name (list->data), name))
-        return list->data;
-    }
-
-  return NULL;
-}
-
-static void
-gtk_css_animated_values_start_css_animations (GtkCssAnimatedValues *values,
-                                              gint64                timestamp,
-                                              GtkStyleContext      *context)
-{
-  GtkCssComputedValues *computed;
-  GtkStyleProviderPrivate *provider;
-  GtkCssValue *durations, *delays, *timing_functions, *animations;
-  GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes;
-  guint i;
-
-  computed = GTK_CSS_COMPUTED_VALUES (values);
-
-  provider = _gtk_style_context_get_style_provider (context);
-  animations = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_NAME);
-  durations = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_DURATION);
-  delays = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_DELAY);
-  timing_functions = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION);
-  iteration_counts = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT);
-  directions = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_DIRECTION);
-  play_states = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE);
-  fill_modes = _gtk_css_computed_values_get_value (computed, GTK_CSS_PROPERTY_ANIMATION_FILL_MODE);
-
-  for (i = 0; i < _gtk_css_array_value_get_n_values (animations); i++)
-    {
-      GtkStyleAnimation *animation;
-      GtkCssKeyframes *keyframes;
-      const char *name;
-      
-      name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animations, i));
-      if (g_ascii_strcasecmp (name, "none") == 0)
-        continue;
-
-      animation = gtk_css_animated_values_find_animation (values, name);
-      if (animation)
-        continue;
-
-      keyframes = _gtk_style_provider_private_get_keyframes (provider, name);
-      if (keyframes == NULL)
-        continue;
-
-      keyframes = _gtk_css_keyframes_compute (keyframes, context);
-
-      animation = _gtk_css_animation_new (name,
-                                          keyframes,
-                                          timestamp + _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, i), 100) * G_USEC_PER_SEC,
-                                          _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, i), 100) * G_USEC_PER_SEC,
-                                          _gtk_css_array_value_get_nth (timing_functions, i),
-                                          _gtk_css_direction_value_get (_gtk_css_array_value_get_nth (directions, i)),
-                                          _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)),
-                                          _gtk_css_fill_mode_value_get (_gtk_css_array_value_get_nth (fill_modes, i)),
-                                          _gtk_css_number_value_get (_gtk_css_array_value_get_nth (iteration_counts, i), 100));
-      values->animations = g_slist_prepend (values->animations, animation);
-    }
-}
-
-/* PUBLIC API */
-
-static void
-gtk_css_animated_values_start_animations (GtkCssAnimatedValues *values,
-                                          gint64                timestamp,
-                                          GtkCssComputedValues *source,
-                                          GtkStyleContext      *context)
-{
-  gtk_css_animated_values_start_transitions (values, timestamp, source);
-  gtk_css_animated_values_start_css_animations (values, timestamp, context);
-}
-
-GtkCssComputedValues *
-_gtk_css_animated_values_new (GtkCssComputedValues *computed,
-                              GtkCssComputedValues *source,
-                              gint64                timestamp,
-                              GtkStyleContext      *context)
-{
-  GtkCssAnimatedValues *values;
-  GtkCssValue *value;
-  GtkBitmask *ignore;
-  guint i;
-
-  g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (computed), NULL);
-  g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (source), NULL);
-  g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
-
-  values = g_object_new (GTK_TYPE_CSS_ANIMATED_VALUES, NULL);
-
-  for (i = 0; ; i++)
-    {
-      value = _gtk_css_computed_values_get_value (computed, i);
-
-      if (value == NULL)
-        break;
-
-      _gtk_css_computed_values_set_value (GTK_CSS_COMPUTED_VALUES (values), 
-                                          i,
-                                          value,
-                                          0,
-                                          _gtk_css_computed_values_get_section (computed, i));
-    }
-
-  _gtk_bitmask_free (GTK_CSS_COMPUTED_VALUES (values)->depends_on_parent);
-  _gtk_bitmask_free (GTK_CSS_COMPUTED_VALUES (values)->equals_parent);
-  _gtk_bitmask_free (GTK_CSS_COMPUTED_VALUES (values)->depends_on_color);
-  _gtk_bitmask_free (GTK_CSS_COMPUTED_VALUES (values)->depends_on_font_size);
-  GTK_CSS_COMPUTED_VALUES (values)->depends_on_parent = _gtk_bitmask_copy (computed->depends_on_parent);
-  GTK_CSS_COMPUTED_VALUES (values)->equals_parent = _gtk_bitmask_copy (computed->equals_parent);
-  GTK_CSS_COMPUTED_VALUES (values)->depends_on_color = _gtk_bitmask_copy (computed->depends_on_color);
-  GTK_CSS_COMPUTED_VALUES (values)->depends_on_font_size = _gtk_bitmask_copy (computed->depends_on_font_size);
-
-  gtk_css_animated_values_start_animations (values, timestamp, source, context);
-
-  ignore = _gtk_css_animated_values_advance (values, timestamp);
-  _gtk_bitmask_free (ignore);
-
-  return GTK_CSS_COMPUTED_VALUES (values);
-}
-
-GtkBitmask *
-_gtk_css_animated_values_advance (GtkCssAnimatedValues *values,
-                                  gint64                timestamp)
-{
-  GtkCssComputedValues *computed;
-  GtkBitmask *changed;
-  GPtrArray *old_animated_values;
-  GSList *list;
-
-  g_return_val_if_fail (GTK_IS_CSS_ANIMATED_VALUES (values), NULL);
-  g_return_val_if_fail (timestamp >= values->current_time, NULL);
-
-  computed = GTK_CSS_COMPUTED_VALUES (values);
-  changed = _gtk_bitmask_new ();
-
-  values->current_time = timestamp;
-  old_animated_values = computed->animated_values;
-  computed->animated_values = NULL;
-
-  list = values->animations;
-  while (list)
-    {
-      GtkStyleAnimation *animation = list->data;
-      
-      list = list->next;
-
-      changed = _gtk_style_animation_set_values (animation,
-                                                 changed,
-                                                 timestamp,
-                                                 GTK_CSS_COMPUTED_VALUES (values));
-      
-      if (_gtk_style_animation_is_finished (animation, timestamp))
-        {
-          values->animations = g_slist_remove (values->animations, animation);
-          g_object_unref (animation);
-        }
-    }
-  
-  if (old_animated_values)
-    g_ptr_array_unref (old_animated_values);
-
-  return changed;
-}
-
-gboolean
-_gtk_css_animated_values_is_finished (GtkCssAnimatedValues *values)
-{
-  g_return_val_if_fail (GTK_IS_CSS_ANIMATED_VALUES (values), TRUE);
-
-  return values->animations == NULL;
-}
diff --git a/gtk/gtkcssanimatedvaluesprivate.h b/gtk/gtkcssanimatedvaluesprivate.h
deleted file mode 100644 (file)
index 65340f5..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright © 2012 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Benjamin Otte <otte@gnome.org>
- */
-
-#ifndef __GTK_CSS_ANIMATED_VALUES_PRIVATE_H__
-#define __GTK_CSS_ANIMATED_VALUES_PRIVATE_H__
-
-#include "gtk/gtkcsscomputedvaluesprivate.h"
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_CSS_ANIMATED_VALUES           (_gtk_css_animated_values_get_type ())
-#define GTK_CSS_ANIMATED_VALUES(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_ANIMATED_VALUES, GtkCssAnimatedValues))
-#define GTK_CSS_ANIMATED_VALUES_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_ANIMATED_VALUES, GtkCssAnimatedValuesClass))
-#define GTK_IS_CSS_ANIMATED_VALUES(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_ANIMATED_VALUES))
-#define GTK_IS_CSS_ANIMATED_VALUES_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_ANIMATED_VALUES))
-#define GTK_CSS_ANIMATED_VALUES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_ANIMATED_VALUES, GtkCssAnimatedValuesClass))
-
-typedef struct _GtkCssAnimatedValues           GtkCssAnimatedValues;
-typedef struct _GtkCssAnimatedValuesClass      GtkCssAnimatedValuesClass;
-
-struct _GtkCssAnimatedValues
-{
-  GtkCssComputedValues parent;
-
-  gint64 current_time;                  /* the current time in our world */
-  GSList *animations;                   /* the running animations */
-};
-
-struct _GtkCssAnimatedValuesClass
-{
-  GtkCssComputedValuesClass parent_class;
-};
-
-GType                   _gtk_css_animated_values_get_type             (void) G_GNUC_CONST;
-
-GtkCssComputedValues *  _gtk_css_animated_values_new                  (GtkCssComputedValues     *computed,
-                                                                       GtkCssComputedValues     *source,
-                                                                       gint64                    timestamp,
-                                                                       GtkStyleContext          *context);
-
-GtkBitmask *            _gtk_css_animated_values_advance              (GtkCssAnimatedValues     *values,
-                                                                       gint64                    timestamp) G_GNUC_WARN_UNUSED_RESULT;
-gboolean                _gtk_css_animated_values_is_finished          (GtkCssAnimatedValues     *values);
-
-
-G_END_DECLS
-
-#endif /* __GTK_CSS_ANIMATED_VALUES_PRIVATE_H__ */
index ea44341ad9a4b5de8fed467c18a5be7eb06c65d2..1450068565c7c8bf6a528473c06dd43b01d51e33 100644 (file)
 
 #include "gtkcsscomputedvaluesprivate.h"
 
+#include "gtkcssanimationprivate.h"
+#include "gtkcssarrayvalueprivate.h"
+#include "gtkcssenumvalueprivate.h"
 #include "gtkcssinheritvalueprivate.h"
 #include "gtkcssinitialvalueprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+#include "gtkcssshorthandpropertyprivate.h"
+#include "gtkcssstringvalueprivate.h"
 #include "gtkcssstylepropertyprivate.h"
+#include "gtkcsstransitionprivate.h"
+#include "gtkstyleanimationprivate.h"
+#include "gtkstylepropertiesprivate.h"
+#include "gtkstylepropertyprivate.h"
+#include "gtkstyleproviderprivate.h"
 
 G_DEFINE_TYPE (GtkCssComputedValues, _gtk_css_computed_values, G_TYPE_OBJECT)
 
@@ -48,6 +59,9 @@ gtk_css_computed_values_dispose (GObject *object)
       values->animated_values = NULL;
     }
 
+  g_slist_free_full (values->animations, g_object_unref);
+  values->animations = NULL;
+
   G_OBJECT_CLASS (_gtk_css_computed_values_parent_class)->dispose (object);
 }
 
@@ -252,3 +266,295 @@ _gtk_css_computed_values_get_difference (GtkCssComputedValues *values,
   return result;
 }
 
+/* TRANSITIONS */
+
+typedef struct _TransitionInfo TransitionInfo;
+struct _TransitionInfo {
+  guint index;                  /* index into value arrays */
+  gboolean pending;             /* TRUE if we still need to handle it */
+};
+
+static void
+transition_info_add (TransitionInfo    infos[GTK_CSS_PROPERTY_N_PROPERTIES],
+                     GtkStyleProperty *property,
+                     guint             index)
+{
+  if (property == NULL)
+    {
+      guint i;
+
+      for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
+        {
+          GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i);
+
+          transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
+        }
+    }
+  else if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
+    {
+      GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
+      guint i;
+
+      for (i = 0; i < _gtk_css_shorthand_property_get_n_subproperties (shorthand); i++)
+        {
+          GtkCssStyleProperty *prop = _gtk_css_shorthand_property_get_subproperty (shorthand, i);
+
+          transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
+        }
+    }
+  else if (GTK_IS_CSS_STYLE_PROPERTY (property))
+    {
+      guint id;
+      
+      if (!_gtk_css_style_property_is_animated (GTK_CSS_STYLE_PROPERTY (property)))
+        return;
+
+      id = _gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (property));
+      g_assert (id < GTK_CSS_PROPERTY_N_PROPERTIES);
+      infos[id].index = index;
+      infos[id].pending = TRUE;
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
+}
+
+static void
+transition_infos_set (TransitionInfo  infos[GTK_CSS_PROPERTY_N_PROPERTIES],
+                      GtkCssValue    *transitions)
+{
+  guint i;
+
+  for (i = 0; i < _gtk_css_array_value_get_n_values (transitions); i++)
+    {
+      GtkStyleProperty *property;
+      GtkCssValue *prop_value;
+
+      prop_value = _gtk_css_array_value_get_nth (transitions, i);
+      if (g_ascii_strcasecmp (_gtk_css_ident_value_get (prop_value), "all") == 0)
+        property = NULL;
+      else
+        {
+          property = _gtk_style_property_lookup (_gtk_css_ident_value_get (prop_value));
+          if (property == NULL)
+            continue;
+        }
+      
+      transition_info_add (infos, property, i);
+    }
+}
+
+static GtkStyleAnimation *
+gtk_css_computed_values_find_transition (GtkCssComputedValues *values,
+                                         guint                 property_id)
+{
+  GSList *list;
+
+  for (list = values->animations; list; list = list->next)
+    {
+      if (!GTK_IS_CSS_TRANSITION (list->data))
+        continue;
+
+      if (_gtk_css_transition_get_property (list->data) == property_id)
+        return list->data;
+    }
+
+  return NULL;
+}
+
+static void
+gtk_css_computed_values_start_transitions (GtkCssComputedValues *values,
+                                           gint64                timestamp,
+                                           GtkCssComputedValues *source)
+{
+  TransitionInfo transitions[GTK_CSS_PROPERTY_N_PROPERTIES] = { { 0, } };
+  GtkCssValue *durations, *delays, *timing_functions;
+  guint i;
+
+  transition_infos_set (transitions, _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_PROPERTY));
+
+  durations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_DURATION);
+  delays = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_DELAY);
+  timing_functions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION);
+
+  for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
+    {
+      GtkStyleAnimation *animation;
+      GtkCssValue *start, *end;
+      double duration, delay;
+
+      if (!transitions[i].pending)
+        continue;
+
+      duration = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, transitions[i].index), 100);
+      delay = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, transitions[i].index), 100);
+      if (duration + delay == 0.0)
+        continue;
+
+      start = _gtk_css_computed_values_get_intrinsic_value (source, i);
+      end = _gtk_css_computed_values_get_intrinsic_value (values, i);
+      if (_gtk_css_value_equal (start, end))
+        {
+          animation = gtk_css_computed_values_find_transition (GTK_CSS_COMPUTED_VALUES (source), i);
+          if (animation)
+            values->animations = g_slist_prepend (values->animations, g_object_ref (animation));
+        }
+      else
+        {
+          animation = _gtk_css_transition_new (i,
+                                               start,
+                                               end,
+                                               _gtk_css_array_value_get_nth (timing_functions, i),
+                                               timestamp + delay * G_USEC_PER_SEC,
+                                               timestamp + (delay + duration) * G_USEC_PER_SEC);
+          values->animations = g_slist_prepend (values->animations, animation);
+        }
+    }
+}
+
+static GtkStyleAnimation *
+gtk_css_computed_values_find_animation (GtkCssComputedValues *values,
+                                        const char           *name)
+{
+  GSList *list;
+
+  for (list = values->animations; list; list = list->next)
+    {
+      if (!GTK_IS_CSS_ANIMATION (list->data))
+        continue;
+
+      if (g_str_equal (_gtk_css_animation_get_name (list->data), name))
+        return list->data;
+    }
+
+  return NULL;
+}
+
+static void
+gtk_css_computed_values_start_css_animations (GtkCssComputedValues *values,
+                                              gint64                timestamp,
+                                              GtkStyleContext      *context)
+{
+  GtkStyleProviderPrivate *provider;
+  GtkCssValue *durations, *delays, *timing_functions, *animations;
+  GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes;
+  guint i;
+
+  provider = _gtk_style_context_get_style_provider (context);
+  animations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_NAME);
+  durations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DURATION);
+  delays = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DELAY);
+  timing_functions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION);
+  iteration_counts = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT);
+  directions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DIRECTION);
+  play_states = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE);
+  fill_modes = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_FILL_MODE);
+
+  for (i = 0; i < _gtk_css_array_value_get_n_values (animations); i++)
+    {
+      GtkStyleAnimation *animation;
+      GtkCssKeyframes *keyframes;
+      const char *name;
+      
+      name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animations, i));
+      if (g_ascii_strcasecmp (name, "none") == 0)
+        continue;
+
+      animation = gtk_css_computed_values_find_animation (values, name);
+      if (animation)
+        continue;
+
+      keyframes = _gtk_style_provider_private_get_keyframes (provider, name);
+      if (keyframes == NULL)
+        continue;
+
+      keyframes = _gtk_css_keyframes_compute (keyframes, context);
+
+      animation = _gtk_css_animation_new (name,
+                                          keyframes,
+                                          timestamp + _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, i), 100) * G_USEC_PER_SEC,
+                                          _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, i), 100) * G_USEC_PER_SEC,
+                                          _gtk_css_array_value_get_nth (timing_functions, i),
+                                          _gtk_css_direction_value_get (_gtk_css_array_value_get_nth (directions, i)),
+                                          _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)),
+                                          _gtk_css_fill_mode_value_get (_gtk_css_array_value_get_nth (fill_modes, i)),
+                                          _gtk_css_number_value_get (_gtk_css_array_value_get_nth (iteration_counts, i), 100));
+      values->animations = g_slist_prepend (values->animations, animation);
+    }
+}
+
+/* PUBLIC API */
+
+void
+_gtk_css_computed_values_start_animations (GtkCssComputedValues *values,
+                                           gint64                timestamp,
+                                           GtkCssComputedValues *source,
+                                           GtkStyleContext      *context)
+{
+  GtkBitmask *ignore;
+
+  gtk_css_computed_values_start_transitions (values, timestamp, source);
+  gtk_css_computed_values_start_css_animations (values, timestamp, context);
+
+  ignore = _gtk_css_computed_values_advance (values, timestamp);
+  _gtk_bitmask_free (ignore);
+}
+
+GtkBitmask *
+_gtk_css_computed_values_advance (GtkCssComputedValues *values,
+                                  gint64                timestamp)
+{
+  GtkBitmask *changed;
+  GPtrArray *old_computed_values;
+  GSList *list;
+
+  g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
+  g_return_val_if_fail (timestamp >= values->current_time, NULL);
+
+  changed = _gtk_bitmask_new ();
+
+  values->current_time = timestamp;
+  old_computed_values = values->animated_values;
+  values->animated_values = NULL;
+
+  list = values->animations;
+  while (list)
+    {
+      GtkStyleAnimation *animation = list->data;
+      
+      list = list->next;
+
+      changed = _gtk_style_animation_set_values (animation,
+                                                 changed,
+                                                 timestamp,
+                                                 GTK_CSS_COMPUTED_VALUES (values));
+      
+      if (_gtk_style_animation_is_finished (animation, timestamp))
+        {
+          values->animations = g_slist_remove (values->animations, animation);
+          g_object_unref (animation);
+        }
+    }
+  
+  if (old_computed_values)
+    g_ptr_array_unref (old_computed_values);
+
+  return changed;
+}
+
+gboolean
+_gtk_css_computed_values_is_static (GtkCssComputedValues *values)
+{
+  GSList *list;
+
+  g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), TRUE);
+
+  for (list = values->animations; list; list = list->next)
+    {
+      if (!_gtk_style_animation_is_static (list->data, values->current_time))
+        return FALSE;
+    }
+
+  return TRUE;
+}
index 1ddc4a776ecc00d86943067448d3eee3e65e1ea2..a79fc6c71fcc4511d9345ab205642718523f5189 100644 (file)
@@ -43,13 +43,17 @@ struct _GtkCssComputedValues
 {
   GObject parent;
 
-  GPtrArray             *values;
-  GPtrArray             *sections;
-  GPtrArray             *animated_values;
-  GtkBitmask            *depends_on_parent;
-  GtkBitmask            *equals_parent;
-  GtkBitmask            *depends_on_color;
-  GtkBitmask            *depends_on_font_size;
+  GPtrArray             *values;               /* the unanimated (aka intrinsic) values */
+  GPtrArray             *sections;             /* sections the values are defined in */
+
+  GPtrArray             *animated_values;      /* NULL or array of animated values/NULL if not animated */
+  gint64                 current_time;         /* the current time in our world */
+  GSList                *animations;           /* the running animations, least important one first */
+
+  GtkBitmask            *depends_on_parent;    /* for intrinsic values */
+  GtkBitmask            *equals_parent;        /* dito */
+  GtkBitmask            *depends_on_color;     /* dito */
+  GtkBitmask            *depends_on_font_size; /* dito */
 };
 
 struct _GtkCssComputedValuesClass
@@ -84,6 +88,13 @@ GtkCssValue *           _gtk_css_computed_values_get_intrinsic_value  (GtkCssCom
 GtkBitmask *            _gtk_css_computed_values_get_difference       (GtkCssComputedValues     *values,
                                                                        GtkCssComputedValues     *other);
 
+void                    _gtk_css_computed_values_start_animations     (GtkCssComputedValues     *values,
+                                                                       gint64                    timestamp,
+                                                                       GtkCssComputedValues     *source,
+                                                                       GtkStyleContext          *context);
+GtkBitmask *            _gtk_css_computed_values_advance              (GtkCssComputedValues     *values,
+                                                                       gint64                    timestamp);
+gboolean                _gtk_css_computed_values_is_static            (GtkCssComputedValues     *values);
 
 G_END_DECLS
 
index 227466219b211e4ba05793afb29828615c8c2a83..07cb1b412894b372c34bfa27dd8aac3c64583574 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "gtkstylecontextprivate.h"
 #include "gtkcontainerprivate.h"
-#include "gtkcssanimatedvaluesprivate.h"
 #include "gtkcssenginevalueprivate.h"
 #include "gtkcssnumbervalueprivate.h"
 #include "gtkcssrgbavalueprivate.h"
@@ -526,7 +525,7 @@ style_data_unref (StyleData *data)
 static gboolean
 style_data_is_animating (StyleData *style_data)
 {
-  return GTK_IS_CSS_ANIMATED_VALUES (style_data->store);
+  return !_gtk_css_computed_values_is_static (style_data->store);
 }
 
 static GtkStyleInfo *
@@ -3011,10 +3010,10 @@ gtk_style_context_update_animations (GtkStyleContext *context,
   
   style_data = style_data_lookup (context);
 
-  differences = _gtk_css_animated_values_advance (GTK_CSS_ANIMATED_VALUES (style_data->store),
+  differences = _gtk_css_computed_values_advance (style_data->store,
                                                   timestamp);
 
-  if (_gtk_css_animated_values_is_finished (GTK_CSS_ANIMATED_VALUES (style_data->store)))
+  if (_gtk_css_computed_values_is_static (style_data->store))
     _gtk_style_context_stop_animations (context);
 
   return differences;
@@ -3043,32 +3042,27 @@ gtk_style_context_should_animate (GtkStyleContext *context)
 
 static void
 gtk_style_context_start_animations (GtkStyleContext      *context,
+                                    GtkCssComputedValues *values,
                                     GtkCssComputedValues *previous,
                                     gint64                timestamp)
 {
-  StyleData *animated;
-
   if (!gtk_style_context_should_animate (context))
     {
       gtk_style_context_stop_animating (context);
       return;
     }
 
-  animated = style_data_new ();
-  animated->store = _gtk_css_animated_values_new (style_data_lookup (context)->store,
-                                                  previous,
-                                                  timestamp,
-                                                  context);
+  _gtk_css_computed_values_start_animations (values,
+                                             timestamp,
+                                             previous,
+                                             context);
 
-  if (_gtk_css_animated_values_is_finished (GTK_CSS_ANIMATED_VALUES (animated->store)))
+  if (_gtk_css_computed_values_is_static (values))
     {
-      style_data_unref (animated);
       gtk_style_context_stop_animating (context);
       return;
     }
 
-  style_info_set_data (context->priv->info, animated);
-  style_data_unref (animated);
   gtk_style_context_start_animating (context);
 }
 
@@ -3172,11 +3166,11 @@ _gtk_style_context_validate (GtkStyleContext  *context,
         {
           StyleData *data;
 
-          gtk_style_context_start_animations (context, current->store, timestamp);
-          change &= ~GTK_CSS_CHANGE_ANIMATE;
-
           data = style_data_lookup (context);
 
+          gtk_style_context_start_animations (context, data->store, current->store, timestamp);
+          change &= ~GTK_CSS_CHANGE_ANIMATE;
+
           changes = _gtk_css_computed_values_get_difference (data->store, current->store);
         }
       else